package edu.ccdb.irods;

import java.io.File;
import java.io.IOException;

import edu.ccdb.irods.methods.CCDBMethods;
import edu.ccdb.irods.signature.SwingWorkerExtension;
import edu.ccdb.irods.signature.UploadStatus;
import edu.sdsc.grid.io.irods.IRODSAccount;
import edu.sdsc.grid.io.irods.IRODSFile;
import edu.sdsc.grid.io.irods.IRODSFileSystem;
import edu.sdsc.grid.io.local.LocalFile;

/*
 * Common IRODS operations
 * 
 * @author Luan Pham
 */

public class IRODSOperations {
	
	/*
	 * Same as the createNewInitalDirectory but create 1 directory at the time
	 */
	public static void createInitalDirectory (String base) throws Exception {
		
		// repeatedly create folder to match the given folder
		String[] folder = base.split("/");
		
		int index = 1;
		StringBuffer baseCurrent = new StringBuffer("/"); // start at root
		boolean stop = false;
		
		// find the first folder to start create folder	
		while ( !stop ) {
			
			IRODSAccount irodsAccount = createNewIRODSAccount( new String (baseCurrent) );
			IRODSFileSystem fileSystem = new IRODSFileSystem( irodsAccount);
			
			IRODSFile file = new IRODSFile(fileSystem, "." ); // plus empty folder, so it seems
			
			// creating new folder at baseCurrent
			System.out.println ("Folder: " + file.getAbsolutePath() );
			
			if ( !file.exists() || index >= folder.length ) { 
				stop = true;				
			}
			else {
				baseCurrent.append(  folder[index] + "/" );	// can't use separator since this is on the server
				index ++;
			}
			
			fileSystem.close();
		}
		
		System.out.println ("BaseCurrent: " + baseCurrent);
		
		// if flag not on then return
		if (!stop) return;
		
		while ( index <= folder.length)  {	// off by one error
			
			createDir(  upOneLevelDirectory (new String(baseCurrent), folder[index-1] ) ,folder[index-1] );
			baseCurrent.append(folder[index] + "/");
			index++;
		}
	}
	
	/*
	 * Get up one level directory. ie /a/b/c/ -> /a/b/ 
	 */
	private static String upOneLevelDirectory (String base, String lastFolder){
		String result = base.replaceAll(lastFolder + "/", "");
		System.out.println (result);
		return result;
	}
	
	/*
	 * Try to create many level at once. Does not work. Use the old method of creating 
	 * a folder at a time.
	 */
	public static void createNewInitalDirectory (String base ) throws Exception {
		
//		createDir("/telescience/home/CCDB_DATA_USER.portal/CCDB_DATA_USER/acquisition/project_10011/", "microscopy_6565" );
		
		IRODSAccount irodsAccount = createNewIRODSAccount("/");
		IRODSFileSystem fileSystem = new IRODSFileSystem( irodsAccount);
		
		IRODSFile file = new IRODSFile(fileSystem, base ); // plus empty folder, so it seems
		
		// Create dir at initial
		System.out.println("Make dir successful? " + file.mkdirs());
//		System.out.println("Make dir successful? " + file.mkdir());
		
		//test
		System.out.println ("create many level at once: " + file.getAbsolutePath() );
		System.out.println ("Exist: " + file.exists() );
//		System.out.println ("Exist: " + isExist(file.getAbsolutePath()) );
		
		fileSystem.close();
	}
	
	public static boolean isExist (String base ) throws Exception{
		
		IRODSAccount irodsAccount = createNewIRODSAccount(base);
		IRODSFileSystem fileSystem = new IRODSFileSystem( irodsAccount);
		
		IRODSFile file = new IRODSFile(fileSystem, "." ); // plus current folder
		
//		System.err.println ("Folder now: '" + file.getAbsolutePath() + "'");
		
		fileSystem.close();
		
		return file.exists() ;
	}
	
	/*
	 * Create a directory on IRODS account 
	 * 
	 * @param	base	your base directory
	 * @param	folder	the folder name 
	 */
	public static boolean createDir (String base, String folder ) throws Exception {
		
        try
        {
        	folder = getProperName (folder);
        	
             for(int j=0;j<2;j++){
            	 
            	 System.out.println("CreateDIR Base:"+base+"   Folder:"+  folder);
	             IRODSAccount irodAccount = createNewIRODSAccount(base);
	             IRODSFileSystem  srbFileSystem = new IRODSFileSystem(irodAccount);

	             IRODSFile srbFile = new IRODSFile(srbFileSystem, folder);
	             System.out.println("Creating folder:"+srbFile.getAbsolutePath());
	             
	             System.out.println("IRODS file exists:"+srbFile.exists());
	             if(!srbFile.exists())
	             {
	                System.err.println(srbFile.mkdir());
	                System.err.println("IRODS DIR:"+srbFile.getAbsolutePath()+" created");
	             }
	             else
	             {
	                 System.err.println("DIR:"+srbFile.getAbsolutePath()+" already exists!");
	             }
	             srbFileSystem.close();
             }
             return true;
        }
        catch(Exception e)
        {
            e.printStackTrace();
            throw new Exception("CANNOT create a IRODS directory: "+e.getMessage());
        }
	}

	
	public static void uploadFile (String fileName, File file, IRODSAccount account, UploadStatus status, SwingWorkerExtension thread ) throws NullPointerException, IOException{
		LocalFile localFile = new LocalFile(file);
		
		// the IRODS path you want to upload to		
		IRODSFileSystem IRODSSystem = new IRODSFileSystem( account );
        
		String IRODSFilePath = account.getHomeDirectory() + "/" + getProperName(fileName);
		IRODSFile fileServer = new IRODSFile(IRODSSystem, IRODSFilePath);
		
		System.out.println("Absolute path: "+fileServer.getAbsolutePath());
		System.out.println("File name: " + fileName	);
		System.out.println("Local Absolute path: " + file.getAbsolutePath());
		System.out.println("----------------------");
		

		CCDBMethods.ccdbCopyFrom( fileServer , file, true, status, thread);
		
//		fileServer.copyFrom(localFile, true); // old method
//		
//        if (!fileServer.checksum().equals(localFile.checksum()))
//        {
//          throw new edu.sdsc.grid.io.srb.SRBException(
//              "File checksum failed!");
//        }
//        else
//        { 
//          System.out.println("REALLY DONE!!");          
//        }
		
		IRODSSystem.close();
	}
	
	private static String getProperName (String name ) {
		
		if (!name.contains(" ") )
			return name;
		
		return name.replace(' ', '_');
		
	}
	
	public static IRODSAccount createNewIRODSAccount (String base){
		return new IRODSAccount(Configuration.SERVER , Configuration.PORT, 
				Configuration.USERNAME, Configuration.PASSWORD, 
				base , Configuration.MCAT_ZONE , Configuration.DEFAULTSTORAGERESOURCE );
	}
}
